gitlab.com/SiaPrime/SiaPrime@v1.4.1/doc/Contract Recovery.md (about)

     1  # File Contract Recovery
     2  
     3  This document lays out the design for file contract recovery using file
     4  contract identifiers. These identifiers are used to identify ones contracts on
     5  the blockchain and to figure out what host the contract was formed with. So renters
     6  can recognize a contract as their own simply by knowing their own wallet seed.
     7  
     8  ## Deriving the contract identifier from the wallet seed
     9  This section explains the multi-step process of deriving the identifier from
    10  the wallet seed.
    11  
    12  #### Renter Seed and Ephemeral Renter Seed
    13  
    14  From the wallet sed we derive a renter seed by combining it with a specifier.
    15  In the following pseudo-code `H` refers to hashing the input using the Blake2B
    16  hashing algorithm.
    17  ```
    18  renterSeed := H(walletSeed || "renter")
    19  ```
    20  For additional security we don't use the renterSeed directly but we hash it again
    21  with the `windowStart` field of the contract divided by 1000. That way we get an
    22  ephemeral seed which changes every 1000 blocks and even if we hand it out to a 
    23  third party explorer, we don't reveal too much information.
    24  ```
    25  ephemeralRenterSeed := H(renterSeed || windowStart / 1000)
    26  ```
    27  
    28  #### Identifier Seed (32 bytes)
    29  The identifier seed is the seed we use to create the identifiers we put into the
    30  arbitrary data of file contract transactions. It can be handed out to third party
    31  to give them read access to the contracts being created by a specific renter.
    32  ```
    33  fileContractIdentifierSeed := H(ephemeralRenterSeed || "identifier_seed")
    34  ```
    35  
    36  #### Secret Key Seed (32 bytes)
    37  The secret key seed is the seed we use to create secret keys for file contracts
    38  which are used to sign revisions. Giving away this seed allows someone to actually
    39  use the contracts derived from it.
    40  ```
    41  fileContractSecretKeySeed := H(ephemeralRenterSeed || "secret_key_seed")
    42  ```
    43  
    44  #### Signing Key Seed (32 bytes)
    45  The signing key seed is used to derive signing keys which are used to sign the
    46  identifiers themselves. This allows us to give away the identifier seed without
    47  allowing a third party to trick us by creating contracts and using our identifier
    48  seed to make us believe we created that contract ourselves.
    49  ```
    50  fileContractSigningKeySeed := H(ephemeralRenterSeed || "signing_key_seed")
    51  ```
    52  
    53  #### Generating the identifier and keys
    54  The identifier, secret key and signing key can be generated simply by using the
    55  corresponding seed and the `SiacoinOutputID` that is spent by the first input of
    56  the transaction that contains the file contract.
    57  ```
    58  fileContractIdentifier := H(fileContractIdentifierSeed || firstInputToFileContract)
    59  
    60  fileContractSecretKey := H(fileContractSecretKeySeed || firstInputToFileContract)
    61  
    62  fileContractSigningKeyPart1 := H(fileContractSigningKeySeed || firstInputToFileContract || 0)
    63  fileContractSigningKeyPart2 := H(fileContractSigningKeySeed || firstInputToFileContract || 1)
    64  fileContractSigningKey := fileContractSigningKeyPart1 || fileContractSigningKeyPart2
    65  ```
    66  The fileContractSigningKey is generated a bit differently since we need 64 bytes
    67  instead of 32 bytes of entropy for Threefish.
    68  
    69  #### Creating the final, signed identifier
    70  The final, signed identifier has a length of 80 bytes and consists of three parts.
    71  
    72  [0:16]  - the file contract identifier prefix for the arbitrary data
    73  
    74  [16:48] - the fileContractIdentifier
    75  
    76  [48:80] - a signature created by encrypting the identifier using Threefish. 
    77  The 32 byte identifier is first padded with zeros to match the Threefish blocksize
    78  of 64 bytes. Then it is encrypted and the first 32 bytes of the ciphertext are
    79  used as the signature.
    80  
    81  To make sure that we know to which host we can go to recover a specific contract,
    82  we also append the Threefish-encrypted public key of the host to the arbitrary
    83  data of the transaction.
    84  
    85  ## Contract Recovery
    86  
    87  Recovering a contract is relatively straightforward.
    88  
    89  1. Check that a contract has the correct arbitrary data prefix
    90  2. Generate the identifier and see if it matches
    91  3. Verify that the signature of the identifier also matches
    92  4. Get the latest revision of the contract from the host
    93  5. Use that revision to pay the host for providing the merkle roots of the uploaded sectors
    94